home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / langs / sozo2 / scsrc20.lzh / LD.LZH / PASS2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-22  |  5.5 KB  |  334 lines

  1.  
  2. /*
  3.  * Copyright (c) 1991 by Sozobon, Limited.  Author: Johann Ruegg
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include "syms.h"
  16. #include "structs.h"
  17.  
  18. #ifndef UNIXHOST
  19. #define SWAPW(a,b)
  20. #define SWAPL(a,b)
  21. #else
  22. #define SWAPW(a,b)    swapw(a,b)
  23. #define SWAPL(a,b)    swapl(a,b)
  24. #endif
  25. extern struct oinfo *ohead;
  26. long textsize, datasize, bsssize, comsize;
  27. extern int mflag, symout, only8, vflag;
  28. extern char *oname;
  29. extern int tb, db, trelb, drelb;
  30.  
  31. #define LBUFSZ    1000
  32. #define LBUFCNT    (LBUFSZ/2)
  33. short *lbuf, *rbuf;
  34.  
  35. int ofd;
  36.  
  37. pass2()
  38. {
  39.     long mkcomm();
  40.     struct oinfo *op;
  41.  
  42.     if (ohead == 0)
  43.         fatal("no objects included");
  44.  
  45.     chk_undefs();
  46.     calc_sizes();
  47.     sec_offs();
  48.     if (mflag)
  49.         see_map();
  50.  
  51.     adjsyms();
  52.     comsize = mkcomm(textsize+datasize+bsssize);
  53.     endsyms();
  54.  
  55.     ofd = open(oname, 1);
  56.     if (ofd < 0)
  57.         ofd = creat(oname, 0700);
  58.     if (ofd < 0)
  59.         fatals("Cant create", oname);
  60.  
  61.     wrhdr();
  62.  
  63.     rewinds();
  64.     relstart();
  65.     mkbufs();
  66.     for (op = ohead; op; op = op->next) {
  67.         flink(op, 0);
  68.     }
  69.     for (op = ohead; op; op = op->next) {
  70.         flink(op, 1);
  71.     }
  72.     if (symout)
  73.         wrsyms(ofd);
  74.     relend();
  75. }
  76.  
  77. mkbufs()
  78. {
  79.     char *mmalloc();
  80.  
  81.     rbuf = (short *)mmalloc(LBUFSZ+4);
  82.     lbuf = (short *)mmalloc(LBUFSZ+4);
  83. }
  84.  
  85. #ifndef MINIX
  86.  
  87. char fill[HDRFILL];
  88.  
  89. wrhdr()
  90. {
  91.     short magic;
  92.     struct hdr_l h;
  93.     long countsyms();
  94.  
  95.     magic = OMAGIC;
  96.     SWAPW(&magic, 1);
  97.     wwrite(ofd, &magic, 2);
  98.     h.tsize = textsize;
  99.     h.dsize = datasize;
  100.     h.bsize = bsssize+comsize;
  101.     if (symout) {
  102.         h.syms = countsyms();
  103.     } else
  104.         h.syms = 0;
  105.     SWAPL(&h, sizeof(h)/4);
  106.     wwrite(ofd, &h, sizeof(h));
  107.     wwrite(ofd, fill, HDRFILL);
  108. }
  109.  
  110. #else
  111.  
  112. struct mhdr {
  113.     long magic, magic2;
  114.     long tsize, dsize, bsize;
  115.     long fill;
  116.     long totsize;
  117.     long syms;
  118. } mh;
  119.  
  120. #define MMAGIC    0x4100301L
  121. #define MMAGIC2    0x20
  122. #define MINSTK    4096
  123.  
  124. extern long mstack;
  125.  
  126. wrhdr()
  127. {
  128.     long countsyms();
  129.  
  130.     mh.magic = MMAGIC;
  131.     mh.magic2 = MMAGIC2;
  132.     mh.tsize = textsize;
  133.     mh.dsize = datasize;
  134.     mh.bsize = bsssize+comsize;
  135.     if (symout)
  136.         mh.syms = countsyms();
  137.     else
  138.         mh.syms = 0;
  139.     if (mstack <= 0)
  140.         mstack = 0x10000L - (mh.dsize+mh.bsize);
  141.     if (mstack < MINSTK)
  142.         mstack = MINSTK;
  143.     mh.totsize = mstack + mh.tsize+mh.dsize+mh.bsize;
  144.     SWAPL(&mh, sizeof(mh)/4);
  145.     wwrite(ofd, &mh, sizeof(mh));
  146. }
  147.  
  148. #endif
  149.  
  150. rewinds()
  151. {
  152.     t_rewind(tb);
  153.     t_rewind(db);
  154.     t_rewind(trelb);
  155.     t_rewind(drelb);
  156. }
  157.  
  158. endsyms()
  159. {
  160.     end_sym("_etext", textsize, (F_TEXT|F_GLBL|F_DEF));
  161.     end_sym("_edata", textsize+datasize, (F_DATA|F_GLBL|F_DEF));
  162.     end_sym("_end", textsize+datasize+bsssize+comsize,
  163.             (F_BSS|F_GLBL|F_DEF));
  164. }
  165.  
  166. calc_sizes()
  167. {
  168.     struct oinfo *op;
  169.  
  170.     op = ohead;
  171.     while (op) {
  172.         op->tbase = textsize;
  173.         op->dbase = datasize;
  174.         op->bbase = bsssize;
  175.  
  176.         textsize += op->oh.tsize;
  177.         datasize += op->oh.dsize;
  178.         bsssize += op->oh.bsize;
  179.  
  180.         op = op->next;
  181.     }
  182. }
  183.  
  184. sec_offs()
  185. {
  186.     struct oinfo *op;
  187.  
  188.     op = ohead;
  189.     while (op) {
  190.         op->dbase += textsize;
  191.         op->bbase += textsize+datasize;
  192.  
  193.         op = op->next;
  194.     }
  195. }
  196.  
  197. see_map()
  198. {
  199.     struct oinfo *op;
  200.  
  201.     op = ohead;
  202.  
  203.     while (op) {
  204.         printf("%s", op->finfo->name);
  205.         if (op->aname[0])
  206.             printf("(%.14s)", op->aname);
  207.         printf(":\t");
  208.         if (op->oh.tsize)
  209.             printf("T %lx @%lx  ", op->oh.tsize,
  210.                 op->tbase);
  211.         if (op->oh.dsize)
  212.             printf("D %lx @%lx  ", op->oh.dsize,
  213.                 op->dbase);
  214.         if (op->oh.bsize)
  215.             printf("B %lx @%lx  ", op->oh.bsize,
  216.                 op->bbase);
  217.         putchar('\n');
  218.  
  219.         op = op->next;
  220.     }
  221. }
  222.  
  223. flink(op, dat)
  224. struct oinfo *op;
  225. {
  226.     long n;
  227.     int i, stuff, relf;
  228.     char *sec;
  229.  
  230.     n = dat ? op->oh.dsize : op->oh.tsize;
  231.     if (n == 0)
  232.         return;
  233.  
  234.     if (dat) {
  235.         stuff = db;
  236.         relf = drelb;
  237.         sec = "data";
  238.     } else {
  239.         stuff = tb;
  240.         relf = trelb;
  241.         sec = "text";
  242.     }
  243.  
  244.     if (vflag) {
  245.         printf("load %s from %s", sec, op->finfo->name);
  246.         if (op->aname[0])
  247.             printf("(%.14s)", op->aname);
  248.         putchar('\n');
  249.     }
  250.  
  251.     while (n > 0) {
  252.         if (n > LBUFSZ)
  253.             i = LBUFSZ;
  254.         else
  255.             i = n;
  256.         t_read(relf, rbuf, i);
  257.         SWAPW(rbuf, i/2);
  258.         if (i < n && rbuf[LBUFCNT-1] == 5) {
  259.             t_read(relf, &rbuf[LBUFCNT], 2);
  260.             SWAPW(&rbuf[LBUFCNT], 1);
  261.             i += 2;
  262.         }
  263.         t_read(stuff, lbuf, i);
  264.  
  265.         link(op, i, lbuf, rbuf);
  266.  
  267.         wwrite(ofd, lbuf, i);
  268.         relout(i, rbuf);
  269.  
  270.         n -= i;
  271.     }
  272. }
  273.  
  274. link(op, size, textp, relp)
  275. struct oinfo *op;
  276. short *textp, *relp;
  277. {
  278.     int num, i;
  279.     long v, findx();
  280.     short x, bufs;
  281. #ifdef UNIXHOST
  282.     long lv;
  283. #endif
  284.  
  285.     num = size/2;
  286.  
  287.     for (i=0; i<num; i++) {
  288.         x = *relp++;
  289.  
  290.         switch (x) {
  291.         case 7:
  292.         case 0:
  293.             textp++;
  294.             break;
  295.         case 5:
  296.             x = *relp;
  297.             if ((x & 7) == 4) {
  298.                 v = findx(x, op->sp, op->havex, relp);
  299.             } else
  300.             switch (x) {
  301.             case 0:
  302.                 goto skip;
  303.                 break;
  304.             case 1:
  305.                 v = op->dbase;
  306.                 break;
  307.             case 2:
  308.                 v = op->tbase;
  309.                 break;
  310.             case 3:
  311.                 v = op->bbase;
  312.                 break;
  313.             default:
  314.                 fatal("Bad relocation value");
  315.             }
  316.  
  317. #ifndef UNIXHOST
  318.             *(long *)textp += v;
  319. #else
  320.             lv = crossl(textp);
  321.             lv += v;
  322.             pcrossl(lv, textp);
  323. #endif
  324. skip:
  325.             textp += 2;
  326.             relp++;
  327.             i++;
  328.             break;
  329.         default:
  330.             fatal("bad relocation value");
  331.         }
  332.     }
  333. }
  334.